package com.vegetable.modules.service.inbound.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vegetable.common.constant.CommonConstant;
import com.vegetable.common.utils.Constant;
import com.vegetable.common.utils.Constant.StockFlowType;
import com.vegetable.common.utils.PageUtils;
import com.vegetable.common.utils.Query;
import com.vegetable.common.utils.R;
import com.vegetable.modules.entity.baseData.AccountDetails;
import com.vegetable.modules.entity.baseData.AddressBook;
import com.vegetable.modules.entity.baseData.ProductSpec;
import com.vegetable.modules.entity.baseData.Products;
import com.vegetable.modules.entity.inbound.AgentDeliveryDetailPack;
import com.vegetable.modules.entity.inbound.OrderCost;
import com.vegetable.modules.entity.inbound.PurchaseDelivery;
import com.vegetable.modules.entity.inbound.PurchaseDeliveryDetail;
import com.vegetable.modules.entity.inbound.po.PurchaseDeliverySequencePO;
import com.vegetable.modules.entity.stock.Stock;
import com.vegetable.modules.entity.stock.po.StockUpdatePO;
import com.vegetable.modules.entity.stock.to.StockFlowDTO;
import com.vegetable.modules.mapper.inbound.PurchaseDeliveryMapper;
import com.vegetable.modules.service.baseData.IAccountDetailsService;
import com.vegetable.modules.service.baseData.IAddressBookService;
import com.vegetable.modules.service.baseData.IProductSpecService;
import com.vegetable.modules.service.baseData.IProductsService;
import com.vegetable.modules.service.inbound.IAgentDeliveryDetailPackService;
import com.vegetable.modules.service.inbound.IOrderCostService;
import com.vegetable.modules.service.inbound.IPurchaseDeliveryDetailService;
import com.vegetable.modules.service.inbound.IPurchaseDeliveryService;
import com.vegetable.modules.service.stock.IStockFlowService;
import com.vegetable.modules.service.stock.IStockService;
import com.vegetable.modules.vo.PurchaseDeliveryDetailVO;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 入库-采购收货表 服务实现类
 * </p>
 *
 * @author wangruijie
 * @since 2024-03-09
 */
@Slf4j
@Service
@AllArgsConstructor
public class PurchaseDeliveryServiceImpl extends ServiceImpl<PurchaseDeliveryMapper, PurchaseDelivery> implements IPurchaseDeliveryService {

    // 订单费用
    private IOrderCostService orderCostService;
    // 商品明细
    private IPurchaseDeliveryDetailService deliveryDetailService;
    // 产地商品
    private IProductsService productsService;
    // 库存表
    private IStockService stockService;
    // 通讯录
    private IAddressBookService addressBookService;
    // 往来明细
    private IAccountDetailsService accountDetailsService;
    // 商品规格
    private IProductSpecService specService;

    private IStockFlowService iStockFlowService;
    // 订单商品包装
    private IAgentDeliveryDetailPackService detailPackService;

    /**
     * 入库采购收货列表查询
     * @param params
     * @return
     */
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        String docNo = (String)params.get("docNo");
        Object state = params.get("state");
        Object regionId = params.get("regionId");
        String startTime = (String)params.get("startTime");
        String endTime = (String)params.get("endTime");
        // 类型：0采购散货，1物流园，2采购包装
        String type = (String)params.get("type");
        Integer type_int = null;
        if (StringUtils.isNotBlank(type)){
            type_int = Integer.valueOf(type);
        }

        IPage<PurchaseDelivery> page = this.page(
                new Query<PurchaseDelivery>().getPage(params),
                new QueryWrapper<PurchaseDelivery>()
                        .between(StringUtils.isNotBlank(startTime), "order_time", startTime, endTime)
                        .eq(ObjectUtils.isNotEmpty(state),"state", state)
                        .eq(ObjectUtils.isNotEmpty(regionId),"region_id", regionId)
                        .eq(ObjectUtils.isNotEmpty(params.get("customerId")),"customer_id", params.get("customerId"))
                        .eq(ObjectUtils.isNotEmpty(type_int),"type", type_int)
                        .like(StringUtils.isNotBlank(docNo),"doc_no", docNo)
                        .orderByDesc("order_time", "create_time")
        );

        return new PageUtils(page);
    }

    /**
     * 详情入库采购收货
     * @param id null
     * @return R
     * @author wrj
     * @since 2024/3/7 下午4:35
     */
    @Override
    public R detailPurchaseDelivery(Long id) {
        PurchaseDelivery purchaseDelivery = baseMapper.selectById(id);
        if (purchaseDelivery == null){
            return R.fail("订单不存在");
        }
        // 查询原订单的其他费用
        log.info("查询原订单的其他费用:{}", purchaseDelivery.getDocNo());
//        QueryWrapper<OrderCost> orderCostQueryWrapper = new QueryWrapper();
//        orderCostQueryWrapper.eq("main_id", purchaseDelivery.getId());
        List<OrderCost> orderCosts = orderCostService.selectByMainId(purchaseDelivery.getId());
        if (CollectionUtils.isNotEmpty(orderCosts)){
            purchaseDelivery.setCosts(orderCosts);
        }
        // 查询原订单的商品
        QueryWrapper<PurchaseDeliveryDetail> detailQuery = new QueryWrapper();
        detailQuery.eq("producer_purchase_id", purchaseDelivery.getId());
        List<PurchaseDeliveryDetail> details = deliveryDetailService.getBaseMapper().selectList(detailQuery);
        if (CollectionUtils.isNotEmpty(details)){
            for (PurchaseDeliveryDetail detail: details) {
                Products products = productsService.getById(detail.getCommodityId());
                detail.setCommodityCode(products.getCommonCode());
                // 查询原订单的商品的其他费用
                log.info("查询原订单的商品的其他费用:{}", JSON.toJSONString(detail.getId()));
                QueryWrapper<OrderCost> detailCost = new QueryWrapper();
                detailCost.in("main_id", detail.getId());
                List<OrderCost> costs = orderCostService.getBaseMapper().selectList(detailCost);
                detail.setCosts(costs);
            }
            purchaseDelivery.setCommodities(details);
        }
        List<StockFlowDTO> flows = iStockFlowService.queryPackOutFlowByOrderNo(purchaseDelivery.getDocNo(), purchaseDelivery.getId());
        purchaseDelivery.setStockFlows(flows);
        List<Stock> stocks = stockService.queryStockByOrderId(purchaseDelivery.getId());
        purchaseDelivery.setStocks(stocks);
        return R.data(purchaseDelivery);
    }

    /**
     * 新增入库采购收货
     * @param purchaseDelivery null
     * @return R
     * @author wrj
     * @since 2024/3/7 下午4:35
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R savePurchaseDelivery(PurchaseDelivery purchaseDelivery) throws Exception {
        // 新增入库采购收货主表
        Set<String> commodityNames = new HashSet<>();
        if (CollectionUtils.isEmpty(purchaseDelivery.getCommodities())){
            throw new Exception("商品列表不能为空");
        }
        Integer number = 0;
        BigDecimal weight = BigDecimal.ZERO;
        BigDecimal goodsMoney = BigDecimal.ZERO;
        shareCost(purchaseDelivery);
        Long orderId = purchaseDelivery.getId();
        // 订单时间
        Date orderTime = purchaseDelivery.getOrderTime();
        // 代办id
        Long agentId = 0L;
        // 代办名字
        String agentName = "";
        // 如果是已经提交的订单 需要处理库存信息
        if((ObjectUtil.isNotNull(orderId)) && selectByDeliverId(orderId).getState() == 1){
            // 原来的采购主表
            PurchaseDelivery oldAD = selectByDeliverId(orderId);
            if(ObjectUtil.isNotNull(oldAD) && oldAD.getState() == 1){
                // 入库单编码
                String docNo = oldAD.getDocNo();
                // 原来的代办交货商品列表
                List<PurchaseDeliveryDetail> oldADDs = deliveryDetailService.selectByDeliverId(orderId);
                for (PurchaseDeliveryDetail dd : purchaseDelivery.getCommodities()) {
                    // 如果详情id是空的，说明是新增。此时正常存储库存
                    if(ObjectUtil.isNull(dd.getId())){
                        deliveryDetailService.saveOrUpdate(dd);
                        saveInStock(orderTime, agentName, docNo, agentId, dd);
                    }else{
                        Optional<PurchaseDeliveryDetail> optional = oldADDs.stream().filter(o -> o.getId().equals(dd.getId())).findAny();
                        if(optional.isPresent()){
                            // 现有的成本
                            BigDecimal nowCost = calOrderCost(dd);
                            PurchaseDeliveryDetail oldDetail = optional.get();
                            List<OrderCost> oldOrderCost = orderCostService.selectByMainId(dd.getId());
                            oldDetail.setCosts(oldOrderCost);
                            // 1 判断规格是否发生变化
                            if((ObjectUtil.isNull(dd.getSpecsId()) && ObjectUtil.isNotNull(oldDetail.getSpecsId()) || (ObjectUtil.isNotNull(dd.getSpecsId()) && !dd.getSpecsId().equals(oldDetail.getSpecsId())))){
                                // todo 回收原来的库存
                                stockService.releaseStock(orderId, dd.getId(), agentId);
                                stockService.releaseStock(orderId, dd.getId(), Constant.WAREHOUSE_ID);
                                // 如果规格发生变化，正常存储库存
                                saveInStock(orderTime, agentName, docNo, agentId, dd);
                            }else {
                                // 判断入库数量是否发生变化
                                Integer nowInNumber = dd.getNumber();
                                Integer oldInNumber = oldDetail.getNumber();
                                if(nowInNumber == 0 && oldInNumber != 0){
                                    // 回收库存 并且 清空1号仓库的库存
                                    stockService.releaseStock(orderId, dd.getId(), Constant.WAREHOUSE_ID);
                                }else if(nowInNumber != 0 && oldInNumber == 0){
                                    saveInStock(orderTime, agentName, docNo, agentId, dd);
                                }else if(nowInNumber != 0 && oldInNumber != 0 && !NumberUtil.equals(new BigDecimal(nowInNumber), new BigDecimal(oldInNumber))){
                                    // 更新对应库存的 现有数量 及 初始数量。并根据difference是否为负数决定是否回收库存
                                    // 入库数量差额
                                    Integer inNumberDifference = NumberUtil.sub(nowInNumber, oldInNumber).intValue();
                                    // 更新对应库存的 现有数量 及 初始数量。并根据difference是否为负数决定是否回收库存
                                    extracted(orderId, dd, Constant.WAREHOUSE_ID, inNumberDifference);
                                }

                                // 现在的成本单价
                                BigDecimal nowCostWeight = NumberUtil.div(nowCost, getActWeight(dd));
                                stockService.updateStockByDetailId(nowCostWeight, dd.getId(), orderId, dd.getUnitPrice());
//                        }
                            }

                        }else{
                            log.info("找不到:{}？不可能。哪个孙子删了", dd.getId());
                        }
                    }
                }
                List<Long> oldADDIds = oldADDs.stream().map(o -> o.getId()).collect(Collectors.toList());
                List<Long> newADDIds = purchaseDelivery.getCommodities().stream().map(o -> o.getId()).collect(Collectors.toList());
                for(Long oldId : oldADDIds){
                    if(!newADDIds.contains(oldId)){
                        deliveryDetailService.deleteById(oldId);
                        stockService.releaseStock(orderId, oldId, Constant.WAREHOUSE_ID);
                        stockService.releaseStock(orderId, oldId, agentId);
                    }
                }
            }
        }

        // 商品id集合
        List<Long> productIds = purchaseDelivery.getCommodities().stream().map(PurchaseDeliveryDetail::getCommodityId).collect(Collectors.toList());
        List<Products> regionCount = productsService.queryListByIds(productIds);
        Map<Integer, List<Products>> listMap = regionCount.stream().collect(Collectors.groupingBy(Products::getRegionId));
        Set<Integer> regionIds = listMap.keySet();
        if(regionIds.size() > 1){
            throw new Exception("商品跨台账，无法正常保存");
        }
        purchaseDelivery.setRegionId(regionCount.get(0).getRegionId());
        for (PurchaseDeliveryDetail deliveryDetail: purchaseDelivery.getCommodities()) {
            commodityNames.add(deliveryDetail.getCommodityName());
            number = number+deliveryDetail.getNumber();
            weight = weight.add(deliveryDetail.getWeight());
            // 暂定单纯商品的金额合计
            goodsMoney = goodsMoney.add(deliveryDetail.getGoodsMoney());
        }
        // 其他费用累计
        BigDecimal otherCost = purchaseDelivery.getCosts().stream().map(OrderCost::getMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
        // 采购费用综合 = 蔬菜费用 + 其他费用
        purchaseDelivery.setMoney(NumberUtil.add(goodsMoney, otherCost));
        purchaseDelivery.setNumber(number);
        purchaseDelivery.setWeight(weight);
        purchaseDelivery.setGoodsMoney(goodsMoney);
        purchaseDelivery.setCommodityNames(String.join("|", commodityNames));
        purchaseDelivery.setVerifyMonet(purchaseDelivery.getMoney());
        if (orderId == null){
            purchaseDelivery.setDocNo(CommonConstant.CGSH+ baseMapper.getNextCode());
            save(purchaseDelivery);
        }else {
            // 修改主表数据
            updateById(purchaseDelivery);
            // 删除其他费用，商品信息，已经商品下的信息
            deleteMethod(purchaseDelivery);
        }
        // 入库采购收货主键
        Long mainId = purchaseDelivery.getId();
        // 保存订单下明细，其他费用
        return saveDetailInfo(mainId, purchaseDelivery);
    }

    private void extracted(Long orderId, PurchaseDeliveryDetail dd, Long warehouseId, Integer inNumberDifference) throws Exception {
        Stock stock = stockService.queryStockByDetailIdAndOrderIdAndWarehouseId(orderId, dd.getId(), warehouseId);
        log.error("");
        if(inNumberDifference > 0){
            // 多了 直接加就好
            StockUpdatePO upPO = new StockUpdatePO();
            upPO.setId(stock.getId());
            upPO.setNumber(stock.getNumber() + inNumberDifference);
            stockService.updateStock(upPO);
        }else if(inNumberDifference < 0){
            // 少了就需要判断少了多少，是否剩余的数量无法补齐。如果补不起，则需要把库存回收
            if((stock.getNumber() + inNumberDifference) >= 0){
                StockUpdatePO upPO = new StockUpdatePO();
                upPO.setId(stock.getId());
                upPO.setNumber(stock.getNumber() + inNumberDifference);
                stockService.updateStock(upPO);
            }else{
                // 1. 释放占用的库存
                stockService.releaseStock(stock);
                // 2.
                Stock stock2 = stockService.queryStockByDetailIdAndOrderIdAndWarehouseId(orderId, dd.getId(), warehouseId);
                StockUpdatePO upPO2 = new StockUpdatePO();
                upPO2.setId(stock.getId());
                upPO2.setNumber(stock2.getNumber() + inNumberDifference);
                stockService.updateStock(upPO2);
            }
        }
    }

    /**
     * 计算入库成本(蔬菜金额 + 其他金额)
     * @param detail
     * @return
     */
    private BigDecimal calOrderCost(PurchaseDeliveryDetail detail) {
        BigDecimal otherCost = BigDecimal.ZERO;
        // 商品其他费用
        List<OrderCost> orderCosts = detail.getCosts();
        if(CollectionUtil.isNotEmpty(orderCosts)){
            for(OrderCost oc : orderCosts){
                otherCost = NumberUtil.add(otherCost, oc.getMoney());
            }
        }
        //成本金额 = 蔬菜金额 + 其他金额
        BigDecimal add = NumberUtil.add(detail.getGoodsMoney(), otherCost);
        return add;
    }

    private void saveInStock(Date orderTime, String agentName, String docNo, Long agentId, PurchaseDeliveryDetail detail) throws Exception {
        // 根据商品id查询商品
        Products products = productsService.getById(detail.getCommodityId());
        if (products == null){
            return;
        }
        List<AgentDeliveryDetailPack> packs = detailPackService.selectByDetailId(detail.getId());
        String packageCost = JSONArray.toJSONString(packs);
        Long specsId = detail.getSpecsId();
        String specsName = null;
        if (ObjectUtil.isNotNull(specsId)){
            ProductSpec productSpec = specService.getById(detail.getSpecsId());
            specsName = productSpec.getName();
        }
        // 录入一号仓库的数量
        int inNumber = detail.getNumber();
        // 商品重量：如果是标品 = 标重 * 数量，如果不是标品 = 毛重
        BigDecimal actWeight = getActWeight(detail);
        // 录入一号仓库的重量
        BigDecimal inWeight = actWeight;
        BigDecimal add = calOrderCost(detail);
        // 录入一号仓库的货物的货款
        BigDecimal inMoney = add;
        if(inNumber != 0 || !NumberUtil.equals(inWeight, BigDecimal.ZERO)){
            stockService.inStock(orderTime, inMoney, products,specsId, specsName, inNumber, inWeight, 0, Constant.WAREHOUSE_ID, Constant.WAREHOUSE_NAME, agentName, packageCost, docNo, detail.getProducerPurchaseId(), detail.getId(), detail.getUnitPrice());
        }else{
            log.info("");
        }
//        // 代办余数大于0，则在代办库存新增一条数据
//        if ((ObjectUtil.isNotNull(detail.getSurplusNumber()) && detail.getSurplusNumber() > 0) ||
//                (ObjectUtil.isNotNull(detail.getSurplusWeight()) && NumberUtil.isGreater(detail.getSurplusWeight(), BigDecimal.ZERO))){
//            stockService.inStock(orderTime, NumberUtil.sub(add, inMoney), products, specsId, specsName, detail.getSurplusNumber(), detail.getSurplusWeight(), 0, agentId, agentName, agentName, packageCost, docNo, detail.getDeliveryId(), detail.getId());
//        }
    }

    private BigDecimal getActWeight(PurchaseDeliveryDetail detail) throws Exception {
        BigDecimal actWeight;
        if(BigDecimal.ZERO.equals(detail.getStandard())){
            actWeight = detail.getWeight();
        }else{
            actWeight = NumberUtil.mul(detail.getStandard(), detail.getNumber());
        }
        if(NumberUtil.equals(BigDecimal.ZERO, actWeight)){
            throw new Exception(detail.getCommodityName() + "重量为空，无法计算成本单价");
        }
        return actWeight;
    }

    private void shareCost(PurchaseDelivery agentDelivery) {
        if (CollectionUtils.isNotEmpty(agentDelivery.getCosts())) {
            // 参与分摊的商品重量合计
            BigDecimal weightTotal = agentDelivery.getCommodities().stream().map(PurchaseDeliveryDetail::getWeight).reduce(BigDecimal.ZERO, BigDecimal::add);
            if(NumberUtil.equals(weightTotal, BigDecimal.ZERO)){
                log.error("异常数据分摊{}", JSONObject.toJSONString(agentDelivery));
                return;
            }
            for (PurchaseDeliveryDetail deliveryDetail: agentDelivery.getCommodities()) {
                deliveryDetail.setCosts(new ArrayList<>());
            }
            for (OrderCost cost : agentDelivery.getCosts()) {
//                    Map<Long, BigDecimal> numberMap = cost.getSerialNumberList();
                // 均摊的单价费用
                BigDecimal unitMoney = cost.getMoney().divide(weightTotal, 6, RoundingMode.HALF_UP);
                for (PurchaseDeliveryDetail deliveryDetail: agentDelivery.getCommodities()) {
                    // 存在
//                        if (numberMap.containsKey(deliveryDetail.getCommodityId())){
                    // 单价*重量= 均摊的金额
                    BigDecimal multiply = unitMoney.multiply(deliveryDetail.getWeight());
//                            BigDecimal money = deliveryDetail.getMoney();
//                            money = money.add(multiply);
//                            deliveryDetail.setMoney(money);
                    // 重新组装商品的其他费用
                    if (CollectionUtils.isNotEmpty(deliveryDetail.getCosts())){
                        OrderCost cost1 = new OrderCost();
                        cost1.setCostClauseId(cost.getCostClauseId());
                        cost1.setCostClauseName(cost.getCostClauseName());
                        cost1.setMoney(multiply);
                        deliveryDetail.getCosts().add(cost1);
                    }else {
                        List<OrderCost> detailCosts = new ArrayList<>();
                        OrderCost cost1 = new OrderCost();
                        cost1.setCostClauseId(cost.getCostClauseId());
                        cost1.setCostClauseName(cost.getCostClauseName());
                        cost1.setMoney(multiply);
                        detailCosts.add(cost1);
                        deliveryDetail.setCosts(detailCosts);
                    }
//                        }
                }
            }
        }else{
            agentDelivery.setCosts(new ArrayList<>());
        }
    }

    /**
     * 保存订单下明细，包装费用，其他费用
     * @param mainId
     * @param purchaseDelivery
     * @return
     */
    private R saveDetailInfo(Long mainId, PurchaseDelivery purchaseDelivery){
        BigDecimal price_unit = purchaseDelivery.getMoney().divide(purchaseDelivery.getWeight(), 2, RoundingMode.HALF_UP);
        List<OrderCost> costs_all = new ArrayList<>();
        // 保存入库采购收货的其他费用
        log.info("保存入库采购收货的其他费用:{}", JSON.toJSONString(purchaseDelivery.getDocNo()));
        if (CollectionUtils.isNotEmpty(purchaseDelivery.getCosts())){
            for (OrderCost cost :purchaseDelivery.getCosts()) {
                cost.setId(null);
                cost.setMainId(mainId);
                costs_all.add(cost);
            }
        }
        // 保存入库采购收货的商品
        log.info("保存入库采购收货的商品:{}", JSON.toJSONString(purchaseDelivery.getDocNo()));
        List<PurchaseDeliveryDetail> commodities = purchaseDelivery.getCommodities();
        for (PurchaseDeliveryDetail deliveryDetail: commodities) {
            // 商品金额+商品的其他费用 =总金额
            BigDecimal money = deliveryDetail.getGoodsMoney();
            if (CollectionUtils.isNotEmpty(deliveryDetail.getCosts())){
                for (OrderCost cost :deliveryDetail.getCosts()) {
                    money = money.add(cost.getMoney());
                }
            }
//            deliveryDetail.setId(null);
            deliveryDetail.setCost(price_unit.multiply(deliveryDetail.getWeight()));
            deliveryDetail.setMoney(money);
            deliveryDetail.setProducerPurchaseId(mainId);
            deliveryDetailService.saveOrUpdate(deliveryDetail);
            // 保存入库采购收货的商品的其他费用
            log.info("保存入库采购收货的商品的其他费用:{}", JSON.toJSONString(purchaseDelivery.getDocNo()));
            if (CollectionUtils.isNotEmpty(deliveryDetail.getCosts())){
                for (OrderCost cost :deliveryDetail.getCosts()) {
                    cost.setId(null);
                    cost.setMainId(deliveryDetail.getId());
                    costs_all.add(cost);
                }
            }
        }
        if (CollectionUtils.isNotEmpty(costs_all)){
            orderCostService.saveBatch(costs_all);
        }
        return R.data(mainId);
    }

    /**
     * 提交入库采购收货
     * @param purchaseDelivery null
     * @return R
     * @author wrj
     * @since 2024/3/7 下午4:35
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R submitPurchaseDelivery(PurchaseDelivery purchaseDelivery) throws Exception {
//        if (purchaseDelivery.getState().intValue() == 1){
//            throw new Exception("订单已入库，不能操作");
//        }
        if(ObjectUtil.isNull(purchaseDelivery.getCustomerId())){
            throw new Exception("请选择加工单位");
        }
        // 暂存--> 正式单
        purchaseDelivery.setState(1);
        R<Long> result = savePurchaseDelivery(purchaseDelivery);
        if (result.isSuccess()){
            // 更新待办的应收金额
            AddressBook addressBook = addressBookService.getById(purchaseDelivery.getCustomerId());
            BigDecimal arrears = addressBook.getArrears();
            // 加上该订单代办应收金额
            arrears = arrears.add(purchaseDelivery.getMoney());
            addressBook.setArrears(arrears);
            addressBookService.updateById(addressBook);
            Long id =  result.getData();
            PurchaseDelivery newDelivery = this.baseMapper.selectById(id);

            // 生成入库库存
            for (PurchaseDeliveryDetail detail : purchaseDelivery.getCommodities()) {
                BigDecimal price_unit = detail.getMoney().divide(detail.getWeight(), 2, RoundingMode.HALF_UP);
                // 根据商品id查询商品
                Products products = productsService.getById(detail.getCommodityId());
                if (products == null){
                    continue;
                }
                 // 采购单类型专成流水类型
                StockFlowType stockFlowType = StockFlowType.getFromPDType(purchaseDelivery.getType());
//                String specsName = null;
//                if (ObjectUtil.isNotNull(detail.getSpecsId())){
//                    ProductSpec productSpec = specService.getById(detail.getSpecsId());
//                    specsName = productSpec.getName();
//                }

                Date orderTime = purchaseDelivery.getOrderTime();
                String docNo = purchaseDelivery.getDocNo();
                // 计算成本
//                BigDecimal inMoney = price_unit.multiply(detail.getWeight());
                String agentName = stockFlowType.getName();
//                String packageCost = "";
//                Long warehouseId = ObjectUtil.isNotNull(purchaseDelivery.getWarehouseId())? purchaseDelivery.getWarehouseId() :  Constant.WAREHOUSE_ID;
//                String warehouseName = ObjectUtil.isNotNull(purchaseDelivery.getWarehouseName())? purchaseDelivery.getWarehouseName() :  Constant.WAREHOUSE_NAME;
//                stockService.inStock(orderTime, inMoney, products, detail.getSpecsId(), specsName, detail.getNumber(), detail.getWeight(), stockFlowType.getValue(), warehouseId, warehouseName, agentName, packageCost, docNo, purchaseDelivery.getId(), detail.getId());
                saveInStock(orderTime, agentName, docNo, 0L, detail);
            }
            // 生成农户的往来明细
            AccountDetails accountDetails = new AccountDetails();
            accountDetails.setStaffType(0); // 0农户
            accountDetails.setPersonId(newDelivery.getCustomerId());
            accountDetails.setDetailType(0); // 收菜
            accountDetails.setOrderId(newDelivery.getId());
            accountDetails.setOrderTime(newDelivery.getOrderTime());
            accountDetails.setDocNo(newDelivery.getDocNo());
            accountDetails.setMoney(newDelivery.getMoney());
            log.info("采购收货保存农户的往来明细：{}", JSON.toJSONString(accountDetails));
            QueryWrapper<AccountDetails> wrapper2 = new QueryWrapper<>();
            wrapper2.lambda().eq(AccountDetails::getOrderId, newDelivery.getId());
            wrapper2.lambda().eq(AccountDetails::getStaffType, 0);
            wrapper2.lambda().eq(AccountDetails::getDetailType, 0);
            accountDetailsService.saveOrUpdate(accountDetails, wrapper2);
        }
        return R.status(true);
    }

    /**
     * 删除入库采购收货
     * @param id null
     * @return R
     * @author wrj
     * @since 2024/3/7 下午4:35
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R deletePurchaseDelivery(Long id) throws Exception {
        PurchaseDelivery purchaseDelivery = baseMapper.selectById(id);
        if (purchaseDelivery == null){
            throw new Exception("订单不存在");
        }
//        if (purchaseDelivery.getState() == 1){
//            throw new Exception("正式订单不允许删除");
//        }
        // 订单号存在于财务管理-付款开支，提示【已付款不能删除】
        if (purchaseDelivery.getVerifyMonet().compareTo(purchaseDelivery.getMoney()) != 0){
            throw new Exception("已付款不能删除");
        }
        baseMapper.deleteById(id);
        deleteMethod(purchaseDelivery);
        stockService.releaseStock(purchaseDelivery.getDocNo());

        return R.status(true);
    }

    /**
     * 查询（未对账金额 > 0）可收款的采购收货
     * @param customerId null
     * @return List<PurchaseDelivery>
     * @author wrj
     * @since 2024/4/15 下午12:21
     */
    @Override
    public List<PurchaseDelivery> canPaymentList(Long customerId, String startTime, String endTime) {
        // 查询原订单的商品
        QueryWrapper<PurchaseDelivery> detailQuery = new QueryWrapper();
        detailQuery.lambda().eq(PurchaseDelivery::getCustomerId, customerId);
        detailQuery.lambda().eq(PurchaseDelivery::getState, 1);
        detailQuery.lambda().eq(PurchaseDelivery::getIsPayFinish, 0);
        if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)){
            detailQuery.lambda().between(PurchaseDelivery::getOrderTime, startTime, endTime);
        }
        detailQuery.orderByDesc("order_time", "create_time");
        List<PurchaseDelivery> details = baseMapper.selectList(detailQuery);
        if(CollectionUtil.isNotEmpty(details)){
            for(PurchaseDelivery pd : details){
                pd.setActualPay(NumberUtil.add(pd.getMoney(), pd.getPremium(), pd.getDiscount().negate()));
            }
        }
        return details;
    }

    @Override
    public PurchaseDelivery selectByDeliverId(Long deliverId) {
        return baseMapper.selectById(deliverId);
    }

    @Override
    public IPage sequence(PurchaseDeliverySequencePO po) {
        IPage iPage = new Page(po.getPage(), po.getLimit());
        IPage<PurchaseDeliveryDetailVO> page = baseMapper.sequence(iPage, po);
        List<PurchaseDeliveryDetailVO> records = page.getRecords();
        if(CollectionUtil.isNotEmpty(records)){
            for(PurchaseDeliveryDetailVO record : records){
                QueryWrapper<AgentDeliveryDetailPack> packQueryWrapper = new QueryWrapper();
                packQueryWrapper.in("detail_id", record.getId());
                List<Stock> stocks = stockService.queryStockByDetailIdAndOrderId(record.getProducerPurchaseId(), record.getId());
                if(CollectionUtil.isNotEmpty(stocks)){
                    record.setCostWeight(stocks.get(0).getCostWeight());
                }
                List<OrderCost> orderCosts = orderCostService.selectByMainId(record.getId());
                if(CollectionUtil.isNotEmpty(orderCosts)){
                    for(OrderCost oc : orderCosts){
                        String costName = oc.getCostClauseName();
                        if("服务费".equals(costName)){
                            record.setServiceFee(oc.getMoney());
                        }else if("运费".equals(costName)){
                            record.setExpenseFee(oc.getMoney());
                        }else if("卸车".equals(costName)){
                            record.setUnLoadingFee(oc.getMoney());
                        }else if("装车".equals(costName)){
                            record.setLoadingFee(oc.getMoney());
                        }else{
                            log.error("--------->{}有个非标的收费类型：{}",record.getDocNo(), oc.getCostClauseName());
                        }
                    }
                }
            }
        }
        return page;
    }

    /**
     * 删除主方法
     * @param purchaseDelivery
     * @return
     */
    private R deleteMethod(PurchaseDelivery purchaseDelivery) throws Exception {
        // 删除原订单的其他费用
        log.info("删除原订单的其他费用:{}", purchaseDelivery.getDocNo());
        orderCostService.deleteByMainId(purchaseDelivery.getId());

        // 删除原订单的商品
        QueryWrapper<PurchaseDeliveryDetail> detailQuery = new QueryWrapper();
        detailQuery.eq("producer_purchase_id", purchaseDelivery.getId());
        List<PurchaseDeliveryDetail> details = deliveryDetailService.getBaseMapper().selectList(detailQuery);
        if (CollectionUtils.isNotEmpty(details)){
            // todo 没有删除订单的商品列表，可能是个隐患
//            // 订单下商品的id集合
            List<Long> detailIds = details.stream().map(PurchaseDeliveryDetail::getId).collect(Collectors.toList());
//            log.info("删除订单下的商品列表:{}", JSON.toJSONString(detailIds));
//            QueryWrapper<PurchaseDeliveryDetail> detailQueryWrapper = new QueryWrapper();
//            detailQueryWrapper.eq("producer_purchase_id", purchaseDelivery.getId());
//            deliveryDetailService.getBaseMapper().delete(detailQueryWrapper);
            // 删除原订单的商品的其他费用
            log.info("删除原订单的商品的其他费用:{}", JSON.toJSONString(detailIds));
            QueryWrapper<OrderCost> detailCost = new QueryWrapper();
            detailCost.in("main_id", detailIds);
            orderCostService.getBaseMapper().delete(detailCost);
        }

        return R.status(true);
    }
}
